#include "LogicFlag.h"

Display LogicFlag::flagTaskByIndex( int index ) {

	string statusMessage;
	string taskName;
	int taskID;
	Data::DataFeedback dataFeedback;
	vector<Task> tasks;
	vector<Task> display;
	int flagState;
	bool outOfBounds;

	outOfBounds = isOutOfBounds(index, _display.getDisplaySize());

	if( outOfBounds ) {
		throw(INDEX_OUT_OF_BOUNDS_ERROR_MESSAGE);
	}

	display = _display.getTaskList();

	taskID = display[index-1].getTaskID();

	_data->getByID(tasks, taskID);

	if( tasks.empty() ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}

	if( display[index-1].getPriority() == UNFLAGGED ) {
		flagState = FLAGGED;
	} else {
		flagState = UNFLAGGED;
	}

	display[index-1].setPriority(flagState);
	_task = display[index-1];

	dataFeedback = _data->executeEdit(_task);

	if( dataFeedback == Data::FAILURE ) {
		throw(FLAG_ERROR_MESSAGE);
	}

	if( dataFeedback == Data::SUCCESS ) {
		_data->getAll(tasks);
		_writer->write(tasks);

		if( flagState ) {
			statusMessage = FLAG_SUCCESS_MESSAGE;
		} else {
			statusMessage = UNFLAG_SUCCESS_MESSAGE;
		}
	}

	_display = Display( statusMessage, display );

	return _display;
}

Display LogicFlag::flagTaskBySearchTerm( string searchTerm ) {
	
	string statusMessage;
	int taskID;
	Data::DataFeedback dataFeedback;
	vector<Task> tasks;
	vector<Task> display;
	bool multipleMatch;
	bool executed;
	bool onDisplay;
	int flagState;

	_data->getBySearchTerm(tasks, searchTerm);

	if( tasks.empty() ) {
		throw(NOT_FOUND_ERROR_MESSAGE);
	}

	display = _display.getTaskList();

	// assume task is not on the display
	onDisplay = false;

	multipleMatch = isMultipleMatches(tasks.size());

	if( multipleMatch ) {
		display = tasks;
		executed = false;
	} else {
		_task = tasks[FIRST_POSITION];
		flagState = _task.getPriority();

		if( flagState == FLAGGED ) {
			flagState = UNFLAGGED;
		} else if( flagState == UNFLAGGED ) {
			flagState = FLAGGED;
		}

		_task.setPriority(flagState);
		taskID = _task.getTaskID();
		dataFeedback = _data->executeEdit(_task);
		executed = true;

		// find if task is on the display
		for( unsigned int i=0; i<display.size(); i++ ) {
			if( display[i].getTaskID() == taskID ) {
				display[i].setPriority(flagState);
				onDisplay = true;
			}
		}

		if( !onDisplay ) {
			display.push_back(_task);
		}
	}

	if( executed == true && dataFeedback == Data::SUCCESS ) {
		tasks.clear();
		_data->getAll(tasks);
		_writer->write(tasks);
		statusMessage = FLAG_SUCCESS_MESSAGE;
	} else {
		statusMessage = FLAG_ERROR_MESSAGE;
	}

	_display = Display( statusMessage, display );

	return _display;
}

const string LogicFlag::FLAG_SUCCESS_MESSAGE = "Item Flagged";
const string LogicFlag::UNFLAG_SUCCESS_MESSAGE = "Item Un-flagged";

const string LogicFlag::FLAG_ERROR_MESSAGE = "Unable To Flag";
const string LogicFlag::UNFLAG_ERROR_MESSAGE = "Unable to Un-flag";

const int LogicFlag::FLAGGED = 1;
const int LogicFlag::UNFLAGGED = 0;

const int LogicFlag::FIRST_POSITION = 0;